﻿using System;
using System.IO;
using System.Xml;
using System.Web;
using System.Data.Common;
using System.Collections.Specialized;
using System.Text.RegularExpressions;
using SyCODE.Component;
using SyCODE.Component.Cryptography;
using SyCODE.Component.DataFactory;

namespace SyCODE.Blog
{
    /// <summary>
    /// 用户注册
    /// </summary>
    public class Register : IHttpHandler
    {
        public bool IsReusable
        {
            get
            {
                return true;
            }
        }
        public void ProcessRequest(HttpContext context)
        {
            NameValueCollection nvc = new NameValueCollection(context.Request.Form);

            //检测验证码防止恶意机器注册
            if (nvc["crc"] == null || MD5.Encrypt(nvc["crc"].ToUpper()) != context.Request.Cookies["reg"].Value)
            {
                Function.ClientScript("$id('crc_img').src='/CRCImage.aspx?n=reg&'+(new Date()).getTime();$id('reg_form').elements['crc'].focus();alert('" + StringResource.GetField("invalidcrcode") + "')");
                return;
            }

            //检测注册信息的有效性
            if (CheckRegisterInfo(nvc))
            {
                nvc.Set("pwd", SHA1.Encrypt(nvc["pwd"]));
                nvc.Set("answer", SHA1.Encrypt(nvc["answer"]));
                nvc.Add("ip", Function.GetUserIp());

                DBAM dbam = new DBAM();
                dbam.BuildParameters("register", nvc);

                if (dbam.Execute() > 0)
                {
                    Login.IssueTicket(nvc["account"], nvc["name"], false);
                    CreateUserDirectory(context, nvc);
                }
                else
                    Function.ClientScript("$id('reg_form').elements['account'].focus();alert('" + StringResource.GetField("hasaccount") + "')");

                dbam.Dispose();
            }
        }

        /// <summary>
        /// 检测注册信息的有效性
        /// </summary>
        /// <param name="nvc">注册信息的键值集合</param>
        /// <returns></returns>
        private bool CheckRegisterInfo(NameValueCollection nvc)
        {
            if (nvc["agree"] == null)
            {
                Function.ClientAlert(StringResource.GetField("mustacceptagreement"));
                return false;
            }
            if (!Regex.IsMatch(nvc["account"], "^([a-z0-9])+[a-z0-9-_]*([a-z0-9])+$"))
            {
                Function.ClientScript("$id('reg_form').elements['account'].focus();alert('" + StringResource.GetField("invalidaccount") + "')");
                return false;
            }
            if (nvc["pwd"].Length < 6 || nvc["pwd"].Length > 32)
            {
                Function.ClientScript("$id('reg_form').elements['pwd'].focus();alert('" + StringResource.GetField("invalidpassword") + "')");
                return false;
            }
            if (nvc["name"].Trim().Length < 1 || nvc["name"].Trim().Length > 16)
            {
                Function.ClientScript("$id('reg_form').elements['name'].focus();alert('" + StringResource.GetField("invalidname") + "')");
                return false;
            }
            if (nvc["question"].Length < 5 || nvc["question"].Length > 20)
            {
                Function.ClientScript("$id('reg_form').elements['question'].focus();alert('" + StringResource.GetField("invalidanswer") + "')");
                return false;
            }
            if (nvc["answer"].Length < 2 || nvc["answer"].Length > 20)
            {
                Function.ClientScript("$id('reg_form').elements['answer'].focus();alert('" + StringResource.GetField("invalidquestion") + "')");
                return false;
            }
            return true;
        }

        /// <summary>
        /// 创建用户目录
        /// </summary>
        /// <param name="nvc">注册信息的键值集合</param>
        private void CreateUserDirectory(HttpContext context, NameValueCollection nvc)
        {
            string userDir = AppPath.GetUserPhysicalPath(nvc["account"]);
            Directory.CreateDirectory(userDir);
            Directory.CreateDirectory(userDir + @"files");
            Directory.CreateDirectory(userDir + @"album\thumb");
            Directory.CreateDirectory(userDir + @"album\comment\0");
            Directory.CreateDirectory(userDir + @"topic");
            Directory.CreateDirectory(userDir + @"head");
            Directory.CreateDirectory(userDir + @"collection");

            CopyEmptyFile(userDir);

            SetBaseInfo(context, nvc, Path.Combine(userDir, "main.xml"));
        }

        /// <summary>
        /// 设置基本信息
        /// </summary>
        /// <param name="nvc">注册信息的键值集合</param>
        /// <param name="path">基本信息文件的存放路径</param>
        private void SetBaseInfo(HttpContext context, NameValueCollection nvc, string path)
        {
            string account = nvc["account"];
            XmlDocument dom = new XmlDocument();
            dom.Load(path);
            XmlNode head = dom.DocumentElement.SelectSingleNode("head");
            head.SelectSingleNode("title").InnerText = String.Format(StringResource.GetField("blogtitle"), nvc["name"]);

            XmlNode author = head.SelectSingleNode("meta[@name='author']");
            author.Attributes["id"].Value = account;
            author.Attributes["content"].Value = nvc["name"];

            string userdir = "/" + account + "/";
            XmlNodeList modules = dom.DocumentElement.SelectNodes("body/a");
            for (int i = 0; i < modules.Count; i++)
            {
                XmlAttribute href = modules[i].Attributes["href"];
                if (href != null)
                {
                    href.Value = userdir + href.Value;
                }
            }

            dom.Save(path);
        }

        /// <summary>
        /// 复制空白文件到用户目录
        /// </summary>
        /// <param name="destDir">目标目录</param>
        private void CopyEmptyFile(string destDir)
        {
            //要复制的所有文件数组
            string[] files = new string[] { "album.xml", "collection.xml", "comment.xml", "last4.xml", "lastleave.xml", "link.xml", "main.xml", "mysort.xml", "store.xml", "style.css", "visitor.xml", "info.xml", @"collection\0.xml", @"head\head.gif", @"album\comment\0\main.xml" };
            
            //文件来源路径
            string source = AppPath.FromRelativePath(@"empty\");
            for (int i = 0; i < files.Length;i++)
            {
                File.Copy(Path.Combine(source, files[i]), Path.Combine(destDir, files[i]), true);
            }
        }
    }
}
